#pragma once
#include "Socket.hpp"
#include "HttpRequest_Response.hpp"
#include "HttpContex.hpp"
#include "Log.hpp"
#include <iostream>
#include <sstream>
#include <vector>
#include <memory>

class HttpClient {
private:
    TcpSocket _socket;
    std::string _server_ip;
    uint16_t _server_port;
    bool _connected = false;
    using RespPtr = std::shared_ptr<HttpResponse>;
public:
    HttpClient(const std::string& ip, uint16_t port) 
        : _server_ip(ip), _server_port(port) { 
            if(!Connect()){
                _connected = false;
            }else {
                _connected = true;
            }
        }
    
    ~HttpClient() {
        _socket.Close();
    }

    // 连接到服务器
    bool Connect() {
        return _socket.Build_Client_Socket(_server_port, _server_ip);
    }
    // 发送POST请求
    RespPtr Post(const std::string& path, 
                     const std::string& body,
                     const std::string& content_type = "application/x-www-form-urlencoded",//正文数据类型
                     const std::unordered_map<std::string, std::string>& headers = {}) 
    {
        if(!_connected){//未连接到服务器
            return nullptr;
        }
        HttpRequest request;

        // 构建请求行
        request._method = "POST";
        request._path = path;
        request._version = "HTTP/1.1";
        
        // 设置必要的头部
        request.SetHeader("Content-Type", content_type);
        request.SetHeader("Content-Length", std::to_string(body.size()));
        
        // 设置自定义头部
        for (const auto& header : headers) {
            request.SetHeader(header.first, header.second);
        }
        // 设置正文
        request._body = body;
        return SendRequest(request);
    }
private:
    // 发送HTTP请求并接收响应
    RespPtr SendRequest(const HttpRequest& request) {
        // 构建HTTP请求字符串
        std::string request_str = BuildRequestString(request);
        
        // 发送请求
        ssize_t sent = _socket.Send(request_str.c_str(), request_str.size());
        if (sent <= 0) {
            _socket.Close();
            LOG_ERR("客户端发送请求失败");
            return nullptr;
        }

        // 接收响应
        return ReceiveResponse();
    }

    // 构建HTTP请求字符串
    std::string BuildRequestString(const HttpRequest& request) 
    {
        std::stringstream ss;
        
        // 请求行
        ss << request._method << " " << request._path << " " << request._version << "\r\n";
        
        // 头部
        for (const auto& header : request._headers) {
            ss << header.first << ": " << header.second << "\r\n";
        }
        
        // 必要的头部（如果未设置）
        if (!request.HasHeader("Host")) {
            ss << "Host: " << _server_ip << ":" << _server_port << "\r\n";
        }
        if (!request.HasHeader("Connection")) {
            ss << "Connection: keep-alive\r\n";
        }
        if (!request.HasHeader("User-Agent")) {
            ss << "User-Agent: HttpClient/1.0\r\n";
        }
        
        // 空行
        ss << "\r\n";
        
        // 正文
        if (!request._body.empty()) {
            ss << request._body;
        }

        return ss.str();
    }

    // 接收HTTP响应
    RespPtr ReceiveResponse() 
    {
        Buffer buffer;
        HttpContext context;
        char temp_buf[4096];
        ssize_t received = 0;
        received = _socket.Recv(temp_buf, sizeof(temp_buf));

        while(received >0 ){//一次性接收所有数据
            buffer.Write(temp_buf, received);
            received = _socket.Recv(temp_buf, sizeof(temp_buf));
        }
        context.RecvAndParseResponse(&buffer);
        if(context.RecvStatus() != RECV_HTTP_OVER){
            LOG_ERR("接收解析HTTP响应失败");  
            return nullptr;
        }
        // 构建HttpResponse对象并返回
        return std::make_shared<HttpResponse>(context.Response());
    }
    
};

